package com.pk.platform.business.core.service.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.script.ScriptContext;
import javax.script.ScriptEngine;

import com.alibaba.fastjson.JSON;
import com.pk.platform.business.core.dao.IListViewDao;
import com.pk.platform.business.core.service.IListViewService;
import com.pk.platform.domain.list.ListDefine;
import com.pk.platform.domain.list.ListField;
import com.pk.platform.domain.list.ListModule;
import com.pk.platform.util.StringConverter;
import com.pk.platform.util.WebUtil;
import com.pk.platform.util.constant.Constant;
import com.pk.platform.util.page.Pager;

public class ListViewServiceImpl implements IListViewService {

	private IListViewDao listViewDao;
	
	@Override
	public void delListDefine(String id) {
		listViewDao.delete(ListDefine.class, id);
	}

	@Override
	public void delListField(String[] id) {
		for(String oneId : id)
		{
			listViewDao.delete(ListField.class, oneId);
		}
	}

	@Override
	public String delListModule(String id) {
		String success = StringConverter.resultStr(Constant.SUCCESS, null);
		String failure = StringConverter.resultStr(Constant.FAILURE, "删除失败，已存在列表定义。");
		String result = success;
		ListModule lm = this.queryListModuleById(id);
		Set<ListDefine> ldSet = lm.getListDefineSet();
		if(ldSet.size() > 0)
		{
			result = failure;
		}
		else
		{
			result = success;
			listViewDao.delete(ListModule.class, id);
		}
		return result;
	}

	@Override
	public ListDefine queryListDefineById(String id) {
		return listViewDao.get(ListDefine.class, id);
	}

	@Override
	public List<Map<String, Object>> queryListDefineByModule(String moduleId,
			Pager pager) {
		return listViewDao.queryListDefineByModule(moduleId, pager);
	}

	@Override
	public List<Map<String, Object>> queryListFieldByDefine(String listId) {
		return listViewDao.queryListFieldByDefine(listId);
	}

	@Override
	public ListField queryListFieldById(String id) {
		return listViewDao.get(ListField.class, id);
	}

	@Override
	public List<Map<String, Object>> queryListModule(Pager pager) {
		return listViewDao.queryListModule(pager);
	}

	@Override
	public ListModule queryListModuleById(String id) {
		return listViewDao.get(ListModule.class, id);
	}

	@Override
	public synchronized String saveListDefine(ListDefine ld) {
		String result = "";
		String success = "({result:'success', id:'@newId'})";
		String failure = "({result:'failure', message:'已存在该编码， 请重新输入列表编码。'})";
		ListModule lm = this.queryListModuleById(ld.getListModule().getId());
		result = success;
		String realCode = lm.getModuleCode() + "_" + ld.getListCode();
		int count = listViewDao.defineCountByCode(realCode, ld.getId());
		if(StringConverter.isNotNull(ld.getId()))
		{
			if(count > 0)
			{
				result = failure;
			}
			else
			{
				ListDefine listDefine = this.queryListDefineById(ld.getId());
				listDefine.setListCode(realCode);
				listDefine.setListName(ld.getListName());
				listDefine.setPageSize(ld.getPageSize());
				listDefine.setHasCheckbox(ld.getHasCheckbox());
				listDefine.setListWidth(ld.getListWidth());
				listDefine.setSqlScript(StringConverter.stringToBlob(ld.getSqlStr()));
			}
		}
		else
		{
			if(count > 0)
			{
				result = failure;
			}
			else
			{
				ld.setListCode(realCode);
				ld.setSqlScript(StringConverter.stringToBlob(ld.getSqlStr()));
				listViewDao.add(ld);
				String newId = ld.getId();
				success = success.replace("@newId", newId);
				result = success;
			}
		}
		return result;
	}

	@Override
	public void saveListField(ListField lf) {
		if(StringConverter.isNotNull(lf.getId()))
		{
			ListField listField = this.queryListFieldById(lf.getId());
			listField.setChineseName(lf.getChineseName());
			listField.setFieldIndex(lf.getFieldIndex());
			listField.setSortable(lf.getSortable());
			listField.setDataType(lf.getDataType());
			listField.setDateFormat(lf.getDateFormat());
			listField.setFieldName(lf.getFieldName());
			listField.setFieldType(lf.getFieldType());
			listField.setFieldWidth(lf.getFieldWidth());
			listField.setScript(lf.getScript());
			listField.setSort(lf.getSort());
		}
		else
		{
			listViewDao.add(lf);
		}
	}

	@Override
	public synchronized String saveListModule(ListModule lm) {
		String result = "";
		String success = "({result:'success'})";
		String failure = "({result:'failure', message:'已存在该编码， 请重新输入模块编码。'})";
		result = success;
		int count = listViewDao.moduleCountByCode(lm.getModuleCode(), lm.getId());
		if(StringConverter.isNotNull(lm.getId())) //更新
		{
			if(count > 0)
			{
				result = failure;
			}
			else
			{
				ListModule listModule = this.queryListModuleById(lm.getId());
				if(!lm.getModuleCode().equals(listModule.getModuleCode()))
				{
					Set<ListDefine> ldSet = listModule.getListDefineSet();
					for(ListDefine ld : ldSet)
					{
						String ldCode = ld.getListCode();
						int index = ldCode.lastIndexOf("_");
						String newCode = lm.getModuleCode() + "_" + ldCode.substring(index + 1, ldCode.length());
						ld.setListCode(newCode);
					}
				}
				listModule.setModuleCode(lm.getModuleCode());
				listModule.setModuleName(lm.getModuleName());
			}
		}
		else //新增
		{
			if(count > 0)
			{
				result = failure;
			}
			else
			{
				lm.setCreateTime(new Date());
				listViewDao.add(lm);
			}
		}
		return result;
	}
	
	public void changeListFieldSort(String[] fieldId, Integer[] sort)
	{
		int len = fieldId.length;
		for(int i = 0; i < len; i++)
		{
			ListField lf = this.queryListFieldById(fieldId[i]);
			lf.setSort(sort[i]);
		}
	}
	
	public Map<String, Object> initGrid(String listCode)
	{
		ListDefine ld = listViewDao.queryListDefineByCode(listCode);
		if(ld == null)
			return null;
		StringBuffer scriptResult = new StringBuffer("<script type='text/javascript'>");
		String jsScriptTemp = "function @name (cellVal, options, row) { @body } ";
		String funcNameTemp = "formatterScript";
		List<String> jsScript = new ArrayList<String>();
		Set<ListField> lfSet = ld.getListFieldSet();
		int len = lfSet.size();
		String[] headerName = new String[len];
		List<Map<String, Object>> columnList = new ArrayList<Map<String,Object>>();
		int i = 0;
		for(ListField lf : lfSet)
		{
			headerName[i] = lf.getChineseName();
			Map<String, Object> columnAttr = new HashMap<String, Object>();
			String fieldIndex = StringConverter.isNotNull(lf.getFieldIndex()) ? lf.getFieldIndex() : lf.getFieldName();
			boolean sortable = Constant.Y.equals(lf.getSortable()) ? true : false;
			columnAttr.put("name", lf.getFieldName());
			columnAttr.put("index", fieldIndex);
			columnAttr.put("align", "center");
			columnAttr.put("sortable", sortable);
			if(StringConverter.isNotNull(lf.getFieldWidth()))
			{
				columnAttr.put("width", lf.getFieldWidth());
			}
			if("Date".equals(lf.getDataType()))
			{
				Map<String, String> formatOpt = new HashMap<String, String>();
				formatOpt.put("srcformat", lf.getDateFormat());
				formatOpt.put("newformat", lf.getDateFormat());
				columnAttr.put("formatter", "date");
				columnAttr.put("formatoptions", formatOpt);
			}
			if("js".equals(lf.getFieldType()))
			{
				String funcName = funcNameTemp + i;
				columnAttr.put("formatter", funcName);
				
				String funcTemp = jsScriptTemp.replace("@name", funcName);
				funcTemp = funcTemp.replace("@body", lf.getScript());
				scriptResult.append(funcTemp);
				jsScript.add(i + "");
			}
			
			i++;
			columnList.add(columnAttr);
		}
		scriptResult.append("</script>");
		String columnJson = JSON.toJSONString(columnList);
		for(String index : jsScript)
		{
			columnJson = columnJson.replace("\"" + funcNameTemp + index + "\"", funcNameTemp + index);
		}
		Map<String, Object> resultMap = new HashMap<String, Object>();
		resultMap.put("headerName", StringConverter.arrayToIntString(headerName));
		resultMap.put("column", columnJson);
		resultMap.put("pageSize", ld.getPageSize());
		resultMap.put("listName", ld.getListName());
		resultMap.put("hasCheckbox", ld.getHasCheckbox());
		resultMap.put("listWidth", ld.getListWidth());
		resultMap.put("formatterScript", scriptResult.toString());
		return resultMap;
	}
	
	public List<Map<String, Object>> loadGridData(String listCode, Map<String, String> paramObj, Pager pager)
	{
		ListDefine ld = listViewDao.queryListDefineByCode(listCode);
		if(ld == null)
			return null;
		ScriptEngine engine = WebUtil.getScriptEngine();
		ScriptContext sc = engine.getContext();
		sc.setAttribute("$DOC", paramObj, ScriptContext.ENGINE_SCOPE);
		String sqlScript = StringConverter.blobToString(ld.getSqlScript());
		try
		{
			String sqlStr = (String)engine.eval(sqlScript, sc);
			return listViewDao.getListByPage(sqlStr, null, pager);
		}
		catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}
	
	

	public IListViewDao getListViewDao() {
		return listViewDao;
	}

	public void setListViewDao(IListViewDao listViewDao) {
		this.listViewDao = listViewDao;
	}

}
